package com.martin.lib_base.net.interceptor

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.martin.lib_base.LibBase
import com.martin.lib_base.base.BaseResponse
import com.martin.lib_base.bean.UserBean
import com.martin.lib_base.constant.ConstantKey
import com.martin.lib_base.ktx.logd
import com.martin.lib_base.ktx.loge
import com.martin.lib_base.ktx.logi
import com.martin.lib_base.ktx.toJson
import com.martin.lib_base.net.NetApply
import com.tencent.mmkv.MMKV
import okhttp3.*
import okhttp3.ResponseBody.Companion.toResponseBody
import org.json.JSONObject

/**
 * @author：Houge
 * @date：2022/9/19
 * @desc：不加密的拦截器
 */
class NoEncryptionInterceptor : Interceptor {

    /**
     * 拦截事件
     */
    override fun intercept(chain: Interceptor.Chain): Response {
        //重建请求
        val request = rebuildRequest(chain.request())
        //发起请求
        val response = chain.proceed(request)

        //判断请求是否成功,是否有返回体
        if (response.isSuccessful && response.body != null) {
            return handleResponse(response)
        }

        return response
    }

    /**
     * 处理请求响应数据
     */
    private fun handleResponse(response: Response): Response {
        val body = response.body
        try {
            body.source().request(Long.MAX_VALUE)
            var bodySource = body.source().buffer.clone().readUtf8()
//            logd("response --- 处理前未格式化 $bodySource")
//            logi("response --- 处理前的数据 ${JSONObject(bodySource).toString(2)}")
            //如果data字段数据不是Object,则剔除,避免后续判定错误
            bodySource = cullErrorTypeData(bodySource, "data")
            val jsonObject = NetApply.gson.fromJson(bodySource, JsonObject::class.java)

            return if (jsonObject.get("ret").asInt == 200 && jsonObject.get("data") != null) {
                logi(
                    "no encrypt ------------------- response success data -------------------\n${
                        JSONObject(
                            jsonObject.get("data").asJsonObject.toString()
                        ).toString(2)
                    }"
                )
                response.newBuilder()
                    .body(
                        jsonObject.get("data")
                            .asJsonObject.toString()
                            .toResponseBody(body.contentType())
                    )
                    .build()

            } else {
                //如果最外层数据报错,则创建内层数据
                val baseResponse = BaseResponse<Any>().apply {
                    code = jsonObject.get("ret").asInt
                    msg = jsonObject.get("msg").asString
                }
                val json = NetApply.gson.toJson(baseResponse).trim()
                response.newBuilder().body(json.toResponseBody(body.contentType())).build()
            }
        } catch (e: Exception) {
            val baseResponse = BaseResponse<Any>().apply {
                code = 999
                msg = "接口数据解析异常 ${e.message}"
            }
            val json = NetApply.gson.toJson(baseResponse).trim()
            return response.newBuilder().body(json.toResponseBody(body.contentType())).build()
        }
    }

    /**
     * 重建请求
     */
    private fun rebuildRequest(request: Request): Request {
        if (request.method != "POST"
            || request.body == null
            || request.header("pass") == "skipAddToken"
        ) {
            return request
        }
        val body = request.body!!

        /*
            获取请求参数
         */
        val jsonObject = getJsonObjectFromRequestBody(body)

        /*
            登录状态下,拼接用户信息
            uid & token
         */
        logi("监听当前是否登录  ${LibBase.isLogin.value}   ${LibBase.userInfo.value}")
        if (LibBase.userId.isNotEmpty() && LibBase.token.isNotEmpty()) {
            if (!jsonObject.keySet().contains("uid")) {
                jsonObject.addProperty("uid", LibBase.userId)
            }
            if (!jsonObject.keySet().contains("token")) {
                jsonObject.addProperty("token", LibBase.token)
            }
        } else if (MMKV.defaultMMKV().decodeBool(ConstantKey.IS_LOGIN, false)) {
            MMKV.defaultMMKV()
                .decodeParcelable(ConstantKey.USER_INFO, UserBean::class.java)?.let {
                    if (!jsonObject.keySet().contains("uid")) {
                        jsonObject.addProperty("uid", it.id)
                    }
                    if (!jsonObject.keySet().contains("token")) {
                        jsonObject.addProperty("token", it.token)
                    }
                }
        }

        logi("request ------ 拼接后的数据  ${jsonObject.toJson()}")

        //生成新的请求体
        val formBody = FormBody.Builder().apply {
            jsonObject.keySet().forEach {
                val element = jsonObject.get(it)
                if (!element.isJsonNull) {
                    add(it, element.asString)
                }
            }
        }.build()

        //返回新的请求
        return request.newBuilder()
            .post(formBody)
            .build()
    }

    /**
     * 剔除错误类型数据
     */
    private fun cullErrorTypeData(
        objString: String,
        key: String,
        isObject: Boolean = true
    ): String {
        val jsonObject = JSONObject(objString)
        val dataForKey = jsonObject.getString(key)
        if (!dataForKey.startsWith(if (isObject) "{" else "[")) {
            jsonObject.remove(key)
        }
        return jsonObject.toString()
    }

    /**
     * 获取[JsonObject] 根据[RequestBody]生成
     */
    private fun getJsonObjectFromRequestBody(body: RequestBody): JsonObject {
        return Gson().fromJson(okio.Buffer().apply {
            body.writeTo(this)
        }.readUtf8(), JsonObject::class.java)
    }
}